#pragma once

#include <iostream>
#include <vector>
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_msg.pb.h"


namespace bitmq
{
    class Router
    {
    public:
        //判断routing_key是否合法
        static bool isLegalRoutingKey(const std::string& routing_key)
        {
            //1.routing_key:判断是否包含非法字符
            for (auto& ch : routing_key)
            {
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    (ch == '_' || ch == '.'))
                {
                    continue;
                }
                return false;
            }
            return true;
        }

        //判断binding_key是否合法
        static bool isLegalBindingKey(const std::string& binding_key)
        {
            //1.routing_key:判断是否包含非法字符
            for (auto& ch : binding_key)
            {
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    (ch == '_' || ch == '.' || 
                    ch == '*' || ch == '#'))
                {
                    continue;
                }
                return false;
            }

            //2.*和#必须独立存在：news.music#.*.#
            //以.进行分割，判断每个单词中是否包含*和#
            std::vector<std::string> sub_words;
            StringHelper::splite(binding_key, ".", sub_words);
            for (auto& word : sub_words)
            {
                if (word.size() > 1 && (word.find("*") != std::string::npos ||
                    word.find("#") != std::string::npos))
                    return false;
            }

            //3. #两边不能出现通配符
            for (int i = 1; i < sub_words.size(); i++)
            {
                if ((sub_words[i] == "*" && sub_words[i-1] == "#") ||
                    (sub_words[i] == "#" && sub_words[i-1] == "*") ||
                    (sub_words[i] == "#" && sub_words[i-1] == "#"))
                    return false;
            }
            return true;
        }

        //路由匹配
        static bool route(ExchangeType type, const std::string& routing_key, const std::string& binding_key)
        {
            if (type == ExchangeType::FANOUT)
            {
                return true;
            }
            else if (type == ExchangeType::DIRECT)
            {
                return routing_key == binding_key;
            }
            else
            {
                //主题交换：
                //1.将binding_key与routiing_key进行字符串分割，得到各个的单词数组
                std::vector<std::string> bkeys, rkeys;
                int n_rkey = StringHelper::splite(routing_key, ".", rkeys);
                int n_bkey = StringHelper::splite(binding_key, ".", bkeys);
                //2.定义标记数组，并初始化[0][0]位置为true，其他位置为false
                std::vector<std::vector<bool>> dp(n_bkey + 1, std::vector<bool>(n_rkey + 1, false));
                dp[0][0] = true; 
                //3.如果binding_key以#起始，则将#对应行的第0列置为1
                if (bkeys[0] == "#")
                    dp[1][0] = true;

                //4.使用rouing_key中的每个单词与binding_key中的每个单词进行匹配
                for (int i = 1; i <= n_bkey; i++)
                {
                    for (int j = 1; j <= n_rkey; j++)
                    {
                        //如果当前bkey是个*或两个单词相同，则匹配成功，继承左上方结果
                        if (bkeys[i-1] == rkeys[j-1] || bkeys[i-1] == "*")
                        {
                            dp[i][j] = dp[i-1][j-1];
                        }
                        else if (bkeys[i-1] == "#")
                        {
                            dp[i][j] = dp[i-1][j-1] | dp[i][j-1] | dp[i-1][j];
                        }
                    }
                }

                return dp[n_bkey][n_rkey];
            }
        }
    };
}